package handler

import (
	"errors"
	"github.com/golang/protobuf/proto"
	"log"
	"net"
	"tcpserv/logger"
	"tcpserv/network"
	"tcpserv/protocol/pb"
)

var (
	SESSION_LOGIN   int32 = 1001
	SESSION_OFFLINE int32 = 1002
	ERROR_PB_FORMAT       = errors.New("pb payload format error")
	ERROR_CNN_SEND        = errors.New("pb payload format error")
)

func init() {
	gCallBacks = make(map[int32]func(r protocol.Request, c net.Conn) (protocol.Response, error), 100)
	Register_SeqenceAll()
}

func OnLogin(req protocol.Request, c net.Conn) (protocol.Response, error) {
	var resp protocol.Response
	resp.LoginResp = &protocol.LoginResp{}
	log.Println(*req.LoginReq.Channel, *req.LoginReq.Username, *req.LoginReq.Passwd)
	//r := req.Login
	return resp, nil
}

func OnOffline(req protocol.Request, c net.Conn) (protocol.Response, error) {
	retok := "ok"
	var status int32 = 100
	var resp protocol.Response
	resp.OfflineResp = &protocol.OfflineResp{}
	resp.OfflineResp.Message = &retok
	resp.OfflineResp.Code = &status

	return resp, nil
}

var gCallBacks map[int32]func(r protocol.Request, c net.Conn) (protocol.Response, error)

func DisPatch(r protocol.Request, c net.Conn) error {
	var sequence int32 = *r.Sequence + 1
	var session int32 = *r.Session
	if handle, ok := gCallBacks[*r.Session]; ok {
		resp, e := handle(r, c)
		if e != nil {
			log.Println(e.Error())
			return e
		}
		resp.Sequence = &sequence
		resp.Session = &session
		b, e := proto.Marshal(&resp)
		if e != nil {
			log.Println(e.Error())
			return ERROR_PB_FORMAT
		}
		_, e = c.Write(b)
		if e != nil {
			return e
		}
	}
	return nil
}

/*

 */
func HandlePack(receiever *network.PackageReceiever, c net.Conn) {
	for {
		pack, e := receiever.ReadNonBlock()
		if e != nil {
			log.Println(e.Error())
			return
		}
		if pack != nil {
			log.Println(c.RemoteAddr(), " [send] ", pack)
			var req protocol.Request
			e := proto.Unmarshal(pack, &req)
			if e != nil {
				logger.LogRealeaseErrorS(e.Error())
				continue
			}
			logger.LogRealeaseInfo(*req.Sequence)
			logger.LogRealeaseInfo(*req.Session)
			e = DisPatch(req, c)
			if e != nil {
				//LogDebugError([]interface{}{e.Error()})
			}
			log.Println("Packet Receiever receieve data ", pack)
		}
	}
}

func Register_SeqenceAll() {
	gCallBacks[SESSION_LOGIN] = OnLogin
	gCallBacks[SESSION_OFFLINE] = OnOffline
}
